home *** CD-ROM | disk | FTP | other *** search
/ AMIGA-CD 2 / Amiga-CD - Volume 2.iso / ungepackte_daten / 1994 / 8 / 05 / term-4.0-source.lha / termPacket.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-03  |  26.4 KB  |  1,207 lines

  1. /*
  2. **    termPacket.c
  3. **
  4. **    Support routines for the `packet window'
  5. **
  6. **    Copyright © 1990-1994 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* A custom message structure. */
  13.  
  14. struct PacketMessage
  15. {
  16.     struct Message     VanillaMessage;
  17.     LONG         Line;
  18. };
  19.  
  20.     /* Some private data required to handle both the window,
  21.      * the editing functions and the command history buffer.
  22.      */
  23.  
  24. STATIC struct Hook         PacketHook;
  25. STATIC STRPTR             PacketContents;
  26.  
  27. STATIC struct Process        *PacketProcess;
  28. STATIC struct SignalSemaphore     PacketSemaphore;
  29. STATIC struct MsgPort        *PacketPort;
  30.  
  31. STATIC LONG             PacketLine;
  32. STATIC LONG             PacketCount;
  33. STATIC STRPTR             PacketString    = NULL;
  34. STATIC LONG             PacketX    = -1,
  35.                  PacketY    = -1,
  36.                  PacketWidth    = -1,
  37.                  PacketHeight    = -1;
  38.  
  39. STATIC BYTE             HasList    = FALSE,
  40.                  Echo        = -1;
  41.  
  42.     /* Gadget IDs */
  43.  
  44. enum    {    GAD_STRING, GAD_LIST };
  45.  
  46.     /* The menu to attach to the packet window. */
  47.  
  48. enum    {    MEN_LOADHISTORY=1,MEN_SAVEHISTORY,MEN_CLEARHISTORY,MEN_OTHERWINDOW,
  49.         MEN_TOGGLE_ECHO,MEN_QUITPANEL
  50.     };
  51.  
  52. STATIC struct NewMenu NewPacketMenu[] =
  53. {
  54.     { NM_TITLE, NULL,         0 , 0,        0, (APTR)0},
  55.     {  NM_ITEM, NULL,         0 , 0,        0, (APTR)MEN_LOADHISTORY},
  56.     {  NM_ITEM, NULL,         0 , 0,        0, (APTR)MEN_SAVEHISTORY},
  57.     {  NM_ITEM, NULL,         0 , 0,        0, (APTR)MEN_CLEARHISTORY},
  58.     {  NM_ITEM, NM_BARLABEL,     0 , 0,        0, (APTR)0},
  59.     {  NM_ITEM, NULL,         0 , 0,        0, (APTR)MEN_OTHERWINDOW},
  60.     {  NM_ITEM, NM_BARLABEL,     0 , 0,        0, (APTR)0},
  61.     {  NM_ITEM, NULL,         0 , TICK,    0, (APTR)MEN_TOGGLE_ECHO},
  62.     {  NM_ITEM, NM_BARLABEL,     0 , 0,        0, (APTR)0},
  63.     {  NM_ITEM, NULL,         0 , 0,        0, (APTR)MEN_QUITPANEL},
  64.     { NM_END, 0,             0 , 0,        0, (APTR)0}
  65. };
  66.  
  67. STATIC VOID __stdargs
  68. PacketDestructor(struct MsgItem *Item)
  69. {
  70.     Signal(PacketProcess,SIG_HANDSHAKE);
  71. }
  72.  
  73. STATIC VOID __regargs
  74. PacketSerWrite(APTR Data,LONG Size)
  75. {
  76.     struct DataMsg Msg;
  77.  
  78.     InitMsgItem(&Msg,PacketDestructor);
  79.  
  80.     Msg . Type = DATAMSGTYPE_WRITE;
  81.     Msg . Data = Data;
  82.     Msg . Size = Size;
  83.  
  84.     Forbid();
  85.  
  86.     ClrSignal(SIG_HANDSHAKE);
  87.  
  88.     PutMsgItem(SpecialQueue,(struct MsgItem *)&Msg);
  89.  
  90.     Wait(SIG_HANDSHAKE);
  91.  
  92.     Permit();
  93. }
  94.  
  95. STATIC VOID __regargs
  96. PacketSerialCommand(STRPTR String)
  97. {
  98.     struct DataMsg Msg;
  99.  
  100.     InitMsgItem(&Msg,PacketDestructor);
  101.  
  102.     if(Echo)
  103.         Msg . Type = DATAMSGTYPE_SERIALCOMMAND;
  104.     else
  105.         Msg . Type = DATAMSGTYPE_SERIALCOMMANDNOECHO;
  106.  
  107.     Msg . Data = String;
  108.  
  109.     Forbid();
  110.  
  111.     ClrSignal(SIG_HANDSHAKE);
  112.  
  113.     PutMsgItem(SpecialQueue,(struct MsgItem *)&Msg);
  114.  
  115.     Wait(SIG_HANDSHAKE);
  116.  
  117.     Permit();
  118. }
  119.  
  120.     /* SendPacketMsg(LONG Line):
  121.      *
  122.      *    Tell the main process to display a certain line.
  123.      */
  124.  
  125. STATIC VOID __regargs
  126. SendPacketMsg(LONG Line)
  127. {
  128.     struct PacketMessage *Msg;
  129.  
  130.     if(Msg = (struct PacketMessage *)AllocVecPooled(sizeof(struct PacketMessage),MEMF_PUBLIC | MEMF_CLEAR))
  131.     {
  132.         Msg -> VanillaMessage . mn_Length    = sizeof(struct PacketMessage);
  133.         Msg -> Line                = Line;
  134.  
  135.         PutMsg(PacketPort,Msg);
  136.     }
  137. }
  138.  
  139.     /* CreateAllGadgets():
  140.      *
  141.      *    Create the packet string gadget.
  142.      */
  143.  
  144. STATIC struct Gadget * __regargs
  145. CreateAllGadgets(LONG Width,struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo)
  146. {
  147.     struct Gadget        *Gadget;
  148.     struct NewGadget     NewGadget;
  149.  
  150.     ObtainSemaphore(&PacketSemaphore);
  151.  
  152.     memset(&NewGadget,0,sizeof(struct NewGadget));
  153.  
  154.     if(Gadget = CreateContext(GadgetList))
  155.     {
  156.         WORD Rest,StringHeight,ProtoHeight;
  157.  
  158.         StringHeight    = 3 + TextAttr . tta_YSize + 3;
  159.         ProtoHeight    = Window -> WScreen -> WBorTop + Window -> WScreen -> Font -> ta_YSize + 1 + 2 + StringHeight + 2;
  160.         Rest        = (PacketHeight - 2 - ProtoHeight - 2) / TextAttr . tta_YSize;
  161.  
  162.         NewGadget . ng_Width        = Width - 26;
  163.         NewGadget . ng_Height        = StringHeight;
  164.         NewGadget . ng_GadgetText    = NULL;
  165.         NewGadget . ng_TextAttr        = &TextAttr;
  166.         NewGadget . ng_VisualInfo    = VisualInfo;
  167.         NewGadget . ng_GadgetID        = GAD_STRING;
  168.         NewGadget . ng_Flags        = 0;
  169.         NewGadget . ng_LeftEdge        = 6;
  170.         NewGadget . ng_TopEdge        = Window -> WScreen -> WBorTop + Window -> WScreen -> Font -> ta_YSize + 2;
  171.  
  172.         GadgetArray[GAD_STRING] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
  173.             GTST_MaxChars,    1024,
  174.             GTST_EditHook,    &PacketHook,
  175.             GA_TabCycle,    FALSE,
  176.         TAG_DONE);
  177.  
  178.             /* If the window is large enough to display the
  179.              * list, create the list view gadget.
  180.              */
  181.  
  182.         if(Rest > 0)
  183.         {
  184.             NewGadget . ng_Height        = 2 + Rest * TextAttr . tta_YSize + 2 + StringHeight;
  185.             NewGadget . ng_GadgetID        = GAD_LIST;
  186.  
  187.             GadgetArray[GAD_LIST] = Gadget = CreateGadget(LISTVIEW_KIND,Gadget,&NewGadget,
  188.                 GTLV_ShowSelected,    GadgetArray[GAD_STRING],
  189.                 GTLV_Labels,        &PacketHistoryList,
  190.                 GTLV_Selected,        PacketCount,
  191.                 GTLV_Top,        PacketCount,
  192.             TAG_DONE);
  193.  
  194.             if(Gadget)
  195.                 HasList = TRUE;
  196.             else
  197.                 HasList = FALSE;
  198.         }
  199.         else
  200.             HasList = FALSE;
  201.     }
  202.  
  203.     ReleaseSemaphore(&PacketSemaphore);
  204.  
  205.     return(Gadget);
  206. }
  207.  
  208.     /* PacketKey(struct Hook *Hook,struct SGWork *Work,ULONG *Msg):
  209.      *
  210.      *    This is a string gadget editing call back routine
  211.      *    (a so-called `hook') which is to perform all the
  212.      *    line editing and command history actions supported
  213.      *    by the packet window.
  214.      */
  215.  
  216. STATIC ULONG __saveds __asm
  217. PacketKey(register __a0 struct Hook *Hook,register __a1 ULONG *Msg,register __a2 struct SGWork *Work)
  218. {
  219.         /* Someone activated the string gadget and
  220.          * hit a key.
  221.          */
  222.  
  223.     if(*Msg == SGH_KEY)
  224.     {
  225.             /* Right-Amiga-key was pressed, release the
  226.              * string gadget so user may select a menu
  227.              * item.
  228.              */
  229.  
  230.         if((Work -> IEvent -> ie_Qualifier & AMIGARIGHT) && Work -> IEvent -> ie_Code < 96)
  231.         {
  232.             if(!(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) && (Work -> IEvent -> ie_Code == KEYCODE_X || Work -> IEvent -> ie_Code == KEYCODE_Q))
  233.                 return(TRUE);
  234.             else
  235.             {
  236.                 Work -> Actions = (Work -> Actions & ~(SGA_USE | SGA_BEEP)) | SGA_END | SGA_REUSE;
  237.                 Work -> Code = '\t';
  238.  
  239.                 CommandWindow = Work -> GadgetInfo -> gi_Window;
  240.                 CommandGadget = Work -> Gadget;
  241.             }
  242.         }
  243.  
  244.         if(Work -> IEvent -> ie_Code >= F01_CODE && Work -> IEvent -> ie_Code <= F10_CODE)
  245.         {
  246.             STATIC UBYTE __far OtherBuffer[2048];
  247.  
  248.             STRPTR    String;
  249.             LONG    Len,Index = Work -> IEvent -> ie_Code - F01_CODE;
  250.  
  251.             Forbid();
  252.  
  253.             if(Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL)
  254.                 String = MacroKeys -> Keys[3][Index];
  255.             else
  256.             {
  257.                 if(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  258.                     String = MacroKeys -> Keys[2][Index];
  259.                 else
  260.                 {
  261.                     if(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  262.                         String = MacroKeys -> Keys[1][Index];
  263.                     else
  264.                         String = MacroKeys -> Keys[0][Index];
  265.                 }
  266.             }
  267.  
  268.             if(Len = strlen(String))
  269.             {
  270.                 if(Work -> BufferPos)
  271.                     CopyMem(Work -> PrevBuffer,OtherBuffer,Work -> BufferPos);
  272.  
  273.                 OtherBuffer[Work -> BufferPos] = 0;
  274.  
  275.                 strcat(OtherBuffer,String);
  276.  
  277.                 strcat(OtherBuffer,&Work -> PrevBuffer[Work -> BufferPos]);
  278.  
  279.                 if(strlen(OtherBuffer) > 1023)
  280.                     OtherBuffer[1023] = 0;
  281.  
  282.                 strcpy(Work -> WorkBuffer,OtherBuffer);
  283.  
  284.                 if(Work -> StringInfo -> UndoBuffer)
  285.                     strcpy(Work -> StringInfo -> UndoBuffer,Work -> PrevBuffer);
  286.  
  287.                 Work -> StringInfo -> UndoPos = Work -> BufferPos;
  288.  
  289.                 Work -> BufferPos    += Len;
  290.                 Work -> NumChars    += Len;
  291.  
  292.                 Work -> Actions = (Work -> Actions & ~SGA_BEEP) | SGA_USE | SGA_REDISPLAY;
  293.             }
  294.  
  295.             Permit();
  296.  
  297.             return(TRUE);
  298.         }
  299.  
  300.             /* The user pressed the cursor-right key to
  301.              * move the cursor to the next word in the buffer.
  302.              */
  303.  
  304.         if(Work -> IEvent -> ie_Code == CURSORRIGHT && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL))
  305.         {
  306.             if(Work -> BufferPos != Work -> NumChars)
  307.             {
  308.                 WORD i,Position = -1;
  309.  
  310.                 for(i = Work -> BufferPos ; i < Work -> NumChars ; i++)
  311.                 {
  312.                     if(Work -> WorkBuffer[i] == ' ')
  313.                     {
  314.                         for( ; i < Work -> NumChars ; i++)
  315.                         {
  316.                             if(Work -> WorkBuffer[i] != ' ')
  317.                             {
  318.                                 Position = i;
  319.                                 break;
  320.                             }
  321.                         }
  322.  
  323.                         break;
  324.                     }
  325.                 }
  326.  
  327.                 if(Position != -1)
  328.                     Work -> BufferPos = Position;
  329.                 else
  330.                     Work -> BufferPos = Work -> NumChars;
  331.  
  332.                 Work -> EditOp = EO_MOVECURSOR;
  333.             }
  334.  
  335.             return(TRUE);
  336.         }
  337.  
  338.             /* The user pressed the cursor-right key to
  339.              * move the cursor to the previous word in the buffer.
  340.              */
  341.  
  342.         if(Work -> IEvent -> ie_Code == CURSORLEFT && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL))
  343.         {
  344.             if(Work -> BufferPos)
  345.             {
  346.                 WORD i,Position = -1;
  347.  
  348.                 for(i = Work -> BufferPos ; i >= 0 ; i--)
  349.                 {
  350.                     if(Work -> WorkBuffer[i] != ' ')
  351.                     {
  352.                         Position = i;
  353.                         break;
  354.                     }
  355.                 }
  356.  
  357.                 if(Position == -1)
  358.                     Position = 0;
  359.  
  360.                 if(Position)
  361.                 {
  362.                     i = Position;
  363.  
  364.                     Position = -1;
  365.  
  366.                     for( ; i >= 0 ; i--)
  367.                     {
  368.                         if(Work -> WorkBuffer[i] == ' ')
  369.                         {
  370.                             Position = i + 1;
  371.                             break;
  372.                         }
  373.                     }
  374.                 }
  375.  
  376.                 if(Position != -1)
  377.                     Work -> BufferPos = Position;
  378.                 else
  379.                     Work -> BufferPos = 0;
  380.  
  381.                 Work -> EditOp = EO_MOVECURSOR;
  382.             }
  383.         }
  384.  
  385.             /* The user pressed the cursor-up key to
  386.              * scroll through the command history.
  387.              */
  388.  
  389.         if(Work -> IEvent -> ie_Code == CURSORUP)
  390.         {
  391.                 /* Shift key: jump to first command
  392.                  * history entry.
  393.                  */
  394.  
  395.             if(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  396.             {
  397.                 if(PacketLine)
  398.                     SendPacketMsg(0);
  399.             }
  400.             else
  401.             {
  402.                 if(PacketLine && PacketCount > 0)
  403.                     SendPacketMsg(PacketCount - 1);
  404.             }
  405.         }
  406.  
  407.             /* The user pressed the cursor-down key to
  408.              * scroll through the command history.
  409.              */
  410.  
  411.         if(Work -> IEvent -> ie_Code == CURSORDOWN)
  412.         {
  413.                 /* Shift key: jump to last command
  414.                  * history entry.
  415.                  */
  416.  
  417.             if(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  418.             {
  419.                 if(PacketLine > 0)
  420.                     SendPacketMsg(PacketLine);
  421.             }
  422.             else
  423.             {
  424.                 if(PacketCount < PacketLine)
  425.                     SendPacketMsg(PacketCount + 1);
  426.             }
  427.         }
  428.  
  429.         return(TRUE);
  430.     }
  431.     else
  432.     {
  433.         if(*Msg == SGH_CLICK)
  434.             return(TRUE);
  435.         else
  436.             return(FALSE);
  437.     }
  438. }
  439.  
  440.     /* HandlePacket():
  441.      *
  442.      *    Process the input coming through the packet window.
  443.      */
  444.  
  445. STATIC BOOLEAN
  446. HandlePacket(VOID)
  447. {
  448.     struct IntuiMessage    *Message;
  449.     struct PacketMessage    *PacketMsg;
  450.     ULONG             MsgClass,MsgCode;
  451.     struct Gadget        *MsgGadget;
  452.     struct FileRequester    *FileRequest;
  453.     UBYTE             DummyBuffer[MAX_FILENAME_LENGTH];
  454.     BOOLEAN             SwapWindow = FALSE;
  455.  
  456.     FOREVER
  457.     {
  458.         if(Wait(PORTMASK(PacketWindow -> UserPort) | SIG_KILL) & SIG_KILL)
  459.             return(TRUE);
  460.  
  461.         while(Message = (struct IntuiMessage *)GT_GetIMsg(PacketWindow -> UserPort))
  462.         {
  463.             MsgClass    = Message -> Class;
  464.             MsgCode        = Message -> Code;
  465.             MsgGadget    = (struct Gadget *)Message -> IAddress;
  466.  
  467.             GT_ReplyIMsg(Message);
  468.  
  469.                 /* Re-enable the string gadget if necessary. */
  470.  
  471.             if(MsgClass == IDCMP_RAWKEY)
  472.             {
  473.                 if(MsgCode == IECODE_UP_PREFIX|RAMIGA_CODE && CommandWindow == PacketWindow)
  474.                     ActivateGadget(CommandGadget,PacketWindow,NULL);
  475.  
  476.                 if(MsgCode == HELP_CODE)
  477.                     GuideDisplay(CONTEXT_PACKETWINDOW);
  478.             }
  479.  
  480.                 /* Handle the menu. */
  481.  
  482.             if(MsgClass == IDCMP_MENUPICK)
  483.             {
  484.                 struct MenuItem *MenuItem;
  485.  
  486.                 while(MsgCode != MENUNULL)
  487.                 {
  488.                     MenuItem = ItemAddress(PacketMenu,MsgCode);
  489.  
  490.                     switch((ULONG)GTMENUITEM_USERDATA(MenuItem))
  491.                     {
  492.                         case MEN_TOGGLE_ECHO:
  493.  
  494.                             if(MenuItem -> Flags & CHECKED)
  495.                                 Echo = TRUE;
  496.                             else
  497.                                 Echo = FALSE;
  498.  
  499.                             break;
  500.  
  501.                         case MEN_QUITPANEL:
  502.  
  503.                             MsgClass = IDCMP_CLOSEWINDOW;
  504.                             break;
  505.  
  506.                         case MEN_LOADHISTORY:
  507.  
  508.                             LT_LockWindow(PacketWindow);
  509.  
  510.                             if(FileRequest = GetFile(PacketWindow,LocaleString(MSG_PACKET_LOAD_HISTORY_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_LOAD_TXT),FALSE))
  511.                             {
  512.                                 if(GetFileSize(DummyBuffer))
  513.                                 {
  514.                                     BPTR SomeFile;
  515.  
  516.                                     if(SomeFile = Open(DummyBuffer,MODE_OLDFILE))
  517.                                     {
  518.                                         if(PacketLine)
  519.                                         {
  520.                                             switch(MyEasyRequest(PacketWindow,LocaleString(MSG_PACKET_PACKET_WINDOW_STILL_HOLDS_LINES_TXT),LocaleString(MSG_PACKET_DISCARD_APPEND_CANCEL_TXT),PacketLine))
  521.                                             {
  522.                                                 case 1:    ClearPacketHistory();
  523.                                                     break;
  524.  
  525.                                                 case 0:    Close(SomeFile);
  526.                                                     SomeFile = NULL;
  527.                                                     break;
  528.                                             }
  529.                                         }
  530.  
  531.                                         if(SomeFile)
  532.                                         {
  533.                                             WORD Len;
  534.  
  535.                                             LineRead(NULL,NULL,NULL);
  536.  
  537.                                             while(Len = LineRead(SomeFile,DummyBuffer,255))
  538.                                             {
  539.                                                 DummyBuffer[Len - 1] = 0;
  540.  
  541.                                                 AddPacketHistory(DummyBuffer);
  542.                                             }
  543.  
  544.                                             Close(SomeFile);
  545.                                         }
  546.                                     }
  547.                                     else
  548.                                         ShowError(PacketWindow,ERR_LOAD_ERROR,IoErr(),DummyBuffer);
  549.                                 }
  550.  
  551.                                 FreeAslRequest(FileRequest);
  552.                             }
  553.  
  554.                             LT_UnlockWindow(PacketWindow);
  555.                             break;
  556.  
  557.                         case MEN_SAVEHISTORY:
  558.  
  559.                             LT_LockWindow(PacketWindow);
  560.  
  561.                             if(!PacketLine)
  562.                                 MyEasyRequest(PacketWindow,LocaleString(MSG_PACKET_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  563.                             else
  564.                             {
  565.                                 if(FileRequest = GetFile(PacketWindow,LocaleString(MSG_PACKET_SAVE_HISTORY_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),FALSE))
  566.                                 {
  567.                                     BPTR SomeFile = NULL;
  568.                                     LONG Error = 0;
  569.  
  570.                                         /* If the file we are about
  571.                                          * to create already exists,
  572.                                          * ask the user whether we are
  573.                                          * to create, append or skip
  574.                                          * the file.
  575.                                          */
  576.  
  577.                                     if(GetFileSize(DummyBuffer))
  578.                                     {
  579.                                         switch(MyEasyRequest(PacketWindow,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  580.                                         {
  581.                                             case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  582.                                                 break;
  583.  
  584.                                             case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  585.                                                 {
  586.                                                     if(Seek(SomeFile,0,OFFSET_END) == -1)
  587.                                                     {
  588.                                                         Close(SomeFile);
  589.  
  590.                                                         SomeFile = NULL;
  591.                                                     }
  592.                                                 }
  593.                                                 break;
  594.                                         }
  595.                                     }
  596.                                     else
  597.                                         SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  598.  
  599.                                     if(!SomeFile)
  600.                                         Error = IoErr();
  601.                                     else
  602.                                     {
  603.                                         struct Node *SomeNode;
  604.  
  605.                                         ObtainSemaphore(&PacketSemaphore);
  606.  
  607.                                         SomeNode = PacketHistoryList . lh_Head;
  608.  
  609.                                         while(SomeNode -> ln_Succ)
  610.                                         {
  611.                                             SetIoErr(0);
  612.  
  613.                                             if(FPrintf(SomeFile,"%s\n",SomeNode -> ln_Name) < 1)
  614.                                             {
  615.                                                 Error = IoErr();
  616.  
  617.                                                 break;
  618.                                             }
  619.  
  620.                                             SomeNode = SomeNode -> ln_Succ;
  621.                                         }
  622.  
  623.                                         Close(SomeFile);
  624.  
  625.                                         if(GetFileSize(DummyBuffer))
  626.                                         {
  627.                                             AddProtection(DummyBuffer,FIBF_EXECUTE);
  628.  
  629.                                             if(Config -> MiscConfig -> CreateIcons)
  630.                                                 AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
  631.                                         }
  632.                                         else
  633.                                             DeleteFile(DummyBuffer);
  634.  
  635.                                         ReleaseSemaphore(&PacketSemaphore);
  636.                                     }
  637.  
  638.                                     if(Error)
  639.                                         ShowError(PacketWindow,ERR_SAVE_ERROR,Error,DummyBuffer);
  640.  
  641.                                     FreeAslRequest(FileRequest);
  642.                                 }
  643.                             }
  644.  
  645.                             LT_UnlockWindow(PacketWindow);
  646.                             break;
  647.  
  648.                         case MEN_CLEARHISTORY:
  649.  
  650.                             LT_LockWindow(PacketWindow);
  651.  
  652.                             ClearPacketHistory();
  653.  
  654.                             LT_UnlockWindow(PacketWindow);
  655.                             break;
  656.  
  657.                         case MEN_OTHERWINDOW:
  658.  
  659.                             SwapWindow = TRUE;
  660.                             break;
  661.                     }
  662.  
  663.                     MsgCode = MenuItem -> NextSelect;
  664.                 }
  665.  
  666.                 ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  667.             }
  668.  
  669.                 /* Shut down. */
  670.  
  671.             if(MsgClass == IDCMP_CLOSEWINDOW)
  672.             {
  673.                 Forbid();
  674.  
  675.                 if(!(SetSignal(0,SIG_KILL) & SIG_KILL))
  676.                     return(FALSE);
  677.                 else
  678.                     return(TRUE);
  679.             }
  680.  
  681.                 /* Activate the string gadget as well. */
  682.  
  683.             if(MsgClass == IDCMP_ACTIVEWINDOW)
  684.                 ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  685.  
  686.             if(MsgClass == IDCMP_NEWSIZE)
  687.             {
  688.                 PacketWindow -> Flags |= WFLG_RMBTRAP;
  689.  
  690.                 strcpy(DummyBuffer,PacketContents);
  691.  
  692.                 RemoveGList(PacketWindow,PacketGadgetList,(UWORD)-1);
  693.  
  694.                 FreeGadgets(PacketGadgetList);
  695.  
  696.                 PacketGadgetList = NULL;
  697.  
  698.                 SetAPen(PacketWindow -> RPort,DrawInfo -> dri_Pens[BACKGROUNDPEN]);
  699.                 RectFill(PacketWindow -> RPort,PacketWindow -> BorderLeft,PacketWindow -> BorderTop,PacketWindow -> Width - PacketWindow -> BorderRight,PacketWindow -> Height - PacketWindow -> BorderBottom);
  700.                 RefreshWindowFrame(PacketWindow);
  701.  
  702.                 PacketHeight    = PacketWindow -> Height;
  703.                 PacketWidth    = PacketWindow -> Width;
  704.  
  705.                 ObtainSemaphore(&PacketSemaphore);
  706.  
  707.                 if(CreateAllGadgets(PacketWindow -> Width,PacketGadgetArray,&PacketGadgetList,VisualInfo))
  708.                 {
  709.                     PacketContents = ((struct StringInfo *)PacketGadgetArray[GAD_STRING] -> SpecialInfo) -> Buffer;
  710.  
  711.                     AddGList(PacketWindow,PacketGadgetList,(UWORD)-1,(UWORD)-1,NULL);
  712.                     RefreshGList(PacketGadgetList,PacketWindow,NULL,(UWORD)-1);
  713.                     GT_RefreshWindow(PacketWindow,NULL);
  714.  
  715.                     ReleaseSemaphore(&PacketSemaphore);
  716.  
  717.                     PacketWindow -> Flags &= ~WFLG_RMBTRAP;
  718.  
  719.                     GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
  720.                         GTST_String,    DummyBuffer,
  721.                     TAG_DONE);
  722.  
  723.                     ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  724.                 }
  725.                 else
  726.                 {
  727.                     DisplayBeep(PacketWindow -> WScreen);
  728.  
  729.                     ReleaseSemaphore(&PacketSemaphore);
  730.  
  731.                     if(!(SetSignal(0,SIG_KILL) & SIG_KILL))
  732.                         return(FALSE);
  733.                     else
  734.                         return(TRUE);
  735.                 }
  736.             }
  737.  
  738.             if(MsgClass == IDCMP_MOUSEBUTTONS)
  739.                 ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  740.  
  741.                 /* User has entered a string. */
  742.  
  743.             if(MsgClass == IDCMP_GADGETUP)
  744.             {
  745.                 switch(MsgGadget -> GadgetID)
  746.                 {
  747.                     case GAD_STRING:
  748.  
  749.                         if(MsgCode != '\t')
  750.                         {
  751.                                 /* Is there anything in the buffer at all? */
  752.  
  753.                             if(PacketContents[0])
  754.                             {
  755.                                 strcpy(DummyBuffer,PacketContents);
  756.  
  757.                                 if(PacketString)
  758.                                 {
  759.                                     if(strcmp(PacketString,DummyBuffer))
  760.                                         AddPacketHistory(DummyBuffer);
  761.  
  762.                                     PacketString = NULL;
  763.                                 }
  764.                                 else
  765.                                     AddPacketHistory(DummyBuffer);
  766.  
  767.                                     /* Convert alien IBM characters. */
  768.  
  769.                                 if(Config -> TerminalConfig -> FontMode == FONT_IBM)
  770.                                 {
  771.                                     UBYTE Char;
  772.                                     WORD i;
  773.  
  774.                                     for(i = 0 ; i < strlen(DummyBuffer) ; i++)
  775.                                     {
  776.                                         if(Char = IBMConversion[DummyBuffer[i]])
  777.                                             DummyBuffer[i] = Char;
  778.                                     }
  779.                                 }
  780.  
  781.                                     /* Execute the command. */
  782.  
  783.                                 PacketSerialCommand(DummyBuffer);
  784.                             }
  785.  
  786.                                 /* Clear the packet window string
  787.                                  * gadget.
  788.                                  */
  789.  
  790.                             GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
  791.                                 GTST_String,    "",
  792.                             TAG_DONE);
  793.  
  794.                                 /* Send a terminating `CR'. */
  795.  
  796.                             switch(Config -> TerminalConfig -> SendCR)
  797.                             {
  798.                                 case CR_ASCR:
  799.  
  800.                                     PacketSerWrite("\r",1);
  801.                                     break;
  802.  
  803.                                 case CR_ASCRLF:
  804.  
  805.                                     PacketSerWrite("\r\n",2);
  806.                                     break;
  807.                             }
  808.  
  809.                                 /* Re-activate the string gadget. */
  810.  
  811.                             ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  812.                         }
  813.  
  814.                         break;
  815.  
  816.                     case GAD_LIST:
  817.  
  818.                         ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  819.                         break;
  820.                 }
  821.             }
  822.  
  823.             if(SwapWindow)
  824.             {
  825.                 BumpWindow(Window);
  826.  
  827.                 SwapWindow = FALSE;
  828.             }
  829.         }
  830.  
  831.         if(PacketMsg = (struct PacketMessage *)GetMsg(PacketPort))
  832.         {
  833.             struct Node *Node;
  834.  
  835.             ObtainSemaphore(&PacketSemaphore);
  836.  
  837.             if(Node = GetListNode(PacketMsg -> Line,&PacketHistoryList))
  838.             {
  839.                 PacketString = Node -> ln_Name;
  840.  
  841.                 if(HasList)
  842.                 {
  843.                     GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  844.                         GTLV_Selected,    PacketMsg -> Line,
  845.                         GTLV_Top,    PacketMsg -> Line,
  846.                     TAG_DONE);
  847.                 }
  848.                 else
  849.                 {
  850.                     GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
  851.                         GTST_String,    Node -> ln_Name,
  852.                     TAG_DONE);
  853.                 }
  854.             }
  855.             else
  856.             {
  857.                 PacketString = NULL;
  858.  
  859.                 GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
  860.                     GTST_String,    "",
  861.                 TAG_DONE);
  862.             }
  863.  
  864.             ReleaseSemaphore(&PacketSemaphore);
  865.  
  866.             PacketCount = PacketMsg -> Line;
  867.  
  868.             FreeVecPooled(PacketMsg);
  869.  
  870.             ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  871.         }
  872.     }
  873. }
  874.  
  875. STATIC VOID __saveds
  876. PacketProcessEntry(VOID)
  877. {
  878.     BOOLEAN RingBack = TRUE;
  879.  
  880.     if(PacketPort = (struct MsgPort *)AllocVecPooled(sizeof(struct MsgPort),MEMF_PUBLIC | MEMF_CLEAR))
  881.     {
  882.         struct Message *Message;
  883.  
  884.         if(PacketMenu = CreateMenus(NewPacketMenu,TAG_DONE))
  885.         {
  886.             if(LayoutMenus(PacketMenu,VisualInfo,
  887.                 GTMN_TextAttr,        &UserFont,
  888.                 GTMN_NewLookMenus,    TRUE,
  889.  
  890.                 AmigaGlyph ? GTMN_AmigaKey :  TAG_IGNORE, AmigaGlyph,
  891.                 CheckGlyph ? GTMN_Checkmark : TAG_IGNORE, CheckGlyph,
  892.             TAG_DONE))
  893.             {
  894.                 LONG ProtoHeight;
  895.  
  896.                 ProtoHeight = Window -> WScreen -> WBorTop + Window -> WScreen -> Font -> ta_YSize + 1 + 2 + 3 + TextAttr . tta_YSize + 3 + 2;
  897.  
  898.                 if(PacketWidth == -1)
  899.                     PacketWidth = Window -> Width;
  900.  
  901.                 if(PacketHeight < ProtoHeight)
  902.                     PacketHeight = ProtoHeight;
  903.  
  904.                 if(PacketX == -1 || (PacketX + PacketWidth > Window -> WScreen -> Width))
  905.                 {
  906.                     PacketX = Window -> LeftEdge;
  907.  
  908.                     if(PacketX + PacketWidth > Window -> WScreen -> Width)
  909.                         PacketWidth = Window -> WScreen -> Width - PacketX;
  910.                 }
  911.  
  912.                 if(PacketY == -1 || (PacketY + PacketHeight > Window -> WScreen -> Height))
  913.                 {
  914.                     PacketY = Window -> TopEdge + Window -> Height;
  915.  
  916.                     if(PacketY + PacketHeight > Window -> WScreen -> Height)
  917.                         PacketHeight = ProtoHeight;
  918.                 }
  919.  
  920.                 if(CreateAllGadgets(PacketWidth,PacketGadgetArray,&PacketGadgetList,VisualInfo))
  921.                 {
  922.                     if(PacketWindow = OpenWindowTags(NULL,
  923.                         WA_Width,        PacketWidth,
  924.                         WA_Height,        PacketHeight,
  925.  
  926.                         WA_Left,        PacketX,
  927.                         WA_Top,            PacketY,
  928.  
  929.                         WA_Activate,        TRUE,
  930.                         WA_DragBar,        TRUE,
  931.                         WA_DepthGadget,        TRUE,
  932.                         WA_CloseGadget,        TRUE,
  933.                         WA_RMBTrap,        TRUE,
  934.                         WA_SizeGadget,        TRUE,
  935.                         WA_MinWidth,        80,
  936.                         WA_MinHeight,        ProtoHeight,
  937.                         WA_MaxWidth,        Window -> WScreen -> Width,
  938.                         WA_MaxHeight,        Window -> WScreen -> Height,
  939.                         WA_CustomScreen,    Window -> WScreen,
  940.                         WA_NoCareRefresh,    TRUE,
  941.                         WA_NewLookMenus,    TRUE,
  942.                         WA_BackFill,        &BackfillHook,
  943.  
  944.                         WA_IDCMP,        STRINGIDCMP | LISTVIEWIDCMP | IDCMP_NEWSIZE | IDCMP_SIZEVERIFY | IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_ACTIVEWINDOW | IDCMP_RAWKEY | IDCMP_MOUSEBUTTONS,
  945.  
  946.                         WA_Title,        LocaleString(MSG_GLOBAL_PACKET_WINDOW_TXT),
  947.  
  948.                         AmigaGlyph ? WA_AmigaKey  : TAG_IGNORE, AmigaGlyph,
  949.                         CheckGlyph ? WA_Checkmark : TAG_IGNORE, CheckGlyph,
  950.                     TAG_DONE))
  951.                     {
  952.                         APTR OldPtr;
  953.  
  954.                         SetAPen(PacketWindow -> RPort,DrawInfo -> dri_Pens[BACKGROUNDPEN]);
  955.                         SetDrMd(PacketWindow -> RPort,JAM1);
  956.                         RectFill(PacketWindow -> RPort,PacketWindow -> BorderLeft,PacketWindow -> BorderTop,PacketWindow -> Width - (PacketWindow -> BorderRight + 1),PacketWindow -> Height - (PacketWindow -> BorderBottom + 1));
  957.  
  958.                         PacketPort -> mp_Flags        = PA_SIGNAL;
  959.                         PacketPort -> mp_SigBit        = PacketWindow -> UserPort -> mp_SigBit;
  960.                         PacketPort -> mp_SigTask    = PacketWindow -> UserPort -> mp_SigTask;
  961.  
  962.                         NewList(&PacketPort -> mp_MsgList);
  963.  
  964.                         PacketHook . h_Entry        = (LONG (*)())PacketKey;
  965.                         PacketHook . h_SubEntry        = NULL;
  966.                         PacketHook . h_Data        = NULL;
  967.  
  968.                         PacketContents = ((struct StringInfo *)PacketGadgetArray[GAD_STRING] -> SpecialInfo) -> Buffer;
  969.  
  970.                         AddGList(PacketWindow,PacketGadgetList,(UWORD)-1,(UWORD)-1,NULL);
  971.                         RefreshGList(PacketGadgetList,PacketWindow,NULL,(UWORD)-1);
  972.                         GT_RefreshWindow(PacketWindow,NULL);
  973.  
  974.                         SetMenuStrip(PacketWindow,PacketMenu);
  975.  
  976.                         PacketWindow -> Flags &= ~WFLG_RMBTRAP;
  977.  
  978.                         ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  979.  
  980.                         PacketProcess = (struct Process *)FindTask(NULL);
  981.  
  982.                         OldPtr = PacketProcess -> pr_WindowPtr;
  983.  
  984.                         PacketProcess -> pr_WindowPtr = PacketWindow;
  985.  
  986.                         Signal(ThisProcess,SIG_HANDSHAKE);
  987.  
  988.                         RingBack = HandlePacket();
  989.  
  990.                         PacketProcess -> pr_WindowPtr = OldPtr;
  991.  
  992.                         PacketWindow -> Flags |= WFLG_RMBTRAP;
  993.  
  994.                         ClearMenuStrip(PacketWindow);
  995.  
  996.                         RemoveGList(PacketWindow,PacketGadgetList,(UWORD)-1);
  997.  
  998.                         PacketX        = PacketWindow -> LeftEdge;
  999.                         PacketY        = PacketWindow -> TopEdge;
  1000.  
  1001.                         PacketWidth    = PacketWindow -> Width;
  1002.                         PacketHeight    = PacketWindow -> Height;
  1003.                 
  1004.                         LT_DeleteWindowLock(PacketWindow);
  1005.  
  1006.                         CloseWindow(PacketWindow);
  1007.  
  1008.                         PacketWindow = NULL;
  1009.                     }
  1010.  
  1011.                     FreeGadgets(PacketGadgetList);
  1012.  
  1013.                     PacketGadgetList = NULL;
  1014.                 }
  1015.             }
  1016.  
  1017.             FreeMenus(PacketMenu);
  1018.  
  1019.             PacketMenu = NULL;
  1020.         }
  1021.  
  1022.         while(Message = GetMsg(PacketPort))
  1023.             FreeVecPooled(Message);
  1024.  
  1025.         FreeVecPooled(PacketPort);
  1026.  
  1027.         PacketPort = NULL;
  1028.     }
  1029.  
  1030.     Forbid();
  1031.  
  1032.     PacketProcess = NULL;
  1033.  
  1034.     if(RingBack)
  1035.         Signal(ThisProcess,SIG_HANDSHAKE);
  1036.     else
  1037.         CheckItem(MEN_PACKET_WINDOW,FALSE);
  1038. }
  1039.  
  1040.     /* ClearPacketHistory():
  1041.      *
  1042.      *    Release the command history.
  1043.      */
  1044.  
  1045. VOID
  1046. ClearPacketHistory()
  1047. {
  1048.     if(PacketProcess)
  1049.     {
  1050.         ObtainSemaphore(&PacketSemaphore);
  1051.  
  1052.         if(HasList)
  1053.         {
  1054.             GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  1055.                 GTLV_Labels,~0,
  1056.             TAG_DONE);
  1057.         }
  1058.     
  1059.         FreeList(&PacketHistoryList);
  1060.     
  1061.         PacketCount = PacketLine = 0;
  1062.     
  1063.         if(HasList)
  1064.         {
  1065.             GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  1066.                 GTLV_Labels,&PacketHistoryList,
  1067.             TAG_DONE);
  1068.         }
  1069.     
  1070.         PacketString = NULL;
  1071.  
  1072.         ReleaseSemaphore(&PacketSemaphore);
  1073.     }
  1074. }
  1075.  
  1076.     /* AddPacketHistory(STRPTR Buffer):
  1077.      *
  1078.      *    Add a line to the packet window command history. This
  1079.      *    works very much the same as the AddLine()-routine.
  1080.      */
  1081.  
  1082. VOID __regargs
  1083. AddPacketHistory(STRPTR Buffer)
  1084. {
  1085.     if(PacketProcess)
  1086.     {
  1087.         struct Node *SomeNode;
  1088.     
  1089.         ObtainSemaphore(&PacketSemaphore);
  1090.  
  1091.         if(HasList)
  1092.         {
  1093.             GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  1094.                 GTLV_Labels,    ~0,
  1095.             TAG_DONE);
  1096.         }
  1097.     
  1098.         if(SomeNode = CreateNode(Buffer))
  1099.         {
  1100.             AddTail(&PacketHistoryList,SomeNode);
  1101.     
  1102.             PacketCount = ++PacketLine;
  1103.         }
  1104.     
  1105.         if(HasList)
  1106.         {
  1107.             GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  1108.                 GTLV_Top,    PacketCount - 1,
  1109.                 GTLV_Labels,    &PacketHistoryList,
  1110.             TAG_DONE);
  1111.         }
  1112.  
  1113.         ReleaseSemaphore(&PacketSemaphore);
  1114.     }
  1115. }
  1116.  
  1117.     /* DeletePacketWindow():
  1118.      *
  1119.      *    Delete the packet window and release the command
  1120.      *    history.
  1121.      */
  1122.  
  1123. VOID __regargs
  1124. DeletePacketWindow(BYTE WindowOnly)
  1125. {
  1126.     CheckItem(MEN_PACKET_WINDOW,FALSE);
  1127.  
  1128.     if(PacketProcess)
  1129.     {
  1130.         Forbid();
  1131.  
  1132.         ClrSignal(SIG_HANDSHAKE);
  1133.  
  1134.         Signal(PacketProcess,SIG_KILL);
  1135.  
  1136.         Wait(SIG_HANDSHAKE);
  1137.  
  1138.         Permit();
  1139.  
  1140.         if(!WindowOnly)
  1141.         {
  1142.             HasList = FALSE;
  1143.  
  1144.             FreeList(&PacketHistoryList);
  1145.     
  1146.             PacketCount = PacketLine = 0;
  1147.     
  1148.             PacketString = NULL;
  1149.         }
  1150.     }
  1151. }
  1152.  
  1153.     /* CreatePacketWindow():
  1154.      *
  1155.      *    Open the packet window and allocate the command history
  1156.      *    buffer.
  1157.      */
  1158.  
  1159. BYTE
  1160. CreatePacketWindow()
  1161. {
  1162.     if(Echo == -1)
  1163.         Echo = Config -> SerialConfig -> Duplex;
  1164.  
  1165.     if(!PacketProcess)
  1166.     {
  1167.         InitSemaphore(&PacketSemaphore);
  1168.  
  1169.         LocalizeMenu(NewPacketMenu,MSG_PACKET_PROJECT_MEN);
  1170.  
  1171.         Forbid();
  1172.  
  1173.         if(CreateNewProcTags(
  1174.             NP_Name,    "term Packet Process",
  1175.             NP_Priority,    SysBase -> ThisTask -> tc_Node . ln_Pri,
  1176.             NP_Entry,    PacketProcessEntry,
  1177.             NP_StackSize,    6000,
  1178.         TAG_DONE))
  1179.         {
  1180.             ClrSignal(SIG_HANDSHAKE);
  1181.  
  1182.             Wait(SIG_HANDSHAKE);
  1183.         }
  1184.  
  1185.         Permit();
  1186.     }
  1187.  
  1188.     if(PacketProcess)
  1189.     {
  1190.         Forbid();
  1191.  
  1192.         ActivateWindow(PacketWindow);
  1193.  
  1194.         CheckItem(MEN_PACKET_WINDOW,TRUE);
  1195.  
  1196.         Permit();
  1197.  
  1198.         return(TRUE);
  1199.     }
  1200.     else
  1201.     {
  1202.         CheckItem(MEN_PACKET_WINDOW,FALSE);
  1203.  
  1204.         return(FALSE);
  1205.     }
  1206. }
  1207.